﻿using Azure;
using Dm;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.RemoteRequest;
using HYHY_Core.Enums;
using HYHY_Core.Tool.Token;
using HYHY_Core.Tool.Tool;
using HYQY_App.Admin_System.Interface;
using HYQY_App.Tool.Image;
using HYQY_Core.Entities.Utils;
using HYQY_Core.Entities.Ware;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SqlSugar.Extensions;
using System.Drawing.Drawing2D;
using static HYQY_App.Admin_System.Dtos.CommodityAdminDto;

namespace HYQY_App.Admin_System.Service
{
    /// <summary>
    /// 商品管理服务
    /// </summary>
    [ApiDescriptionSettings(ApiGroupEnumsCode.CommodityAdmin, Name = "CommodityAdmin")]
    public class CommodityAdminService : IDynamicApiController, ITransient, ICommodityAdminService
    {
        /// <summary>
        /// sql
        /// </summary>
        private readonly ISqlSugarClient _db;

        /// <summary>
        /// 调用公共添加图片接口
        /// </summary>
        private readonly IImageService _addImageService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        public CommodityAdminService(ISqlSugarClient db, IImageService addImageService)
        {
            _db = db;
            _addImageService = addImageService;
        }

        /// <summary>
        /// 商品列表-下拉框-获取点单类目
        /// </summary>
        /// <returns></returns>
        public async Task<List<SelectCategoryList_BelowOutPut>> SelectCategoryList_Below()
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            var list = await _db.Queryable<Category>()
                .Select(it => new SelectCategoryList_BelowOutPut
                {
                    Id = it.Id,
                    Name = it.Name,
                    Sort = it.Sort
                })
                .ToListAsync();

            return list;
        }

        /// <summary>
        /// 商品列表
        /// </summary>
        /// <returns></returns>
        public async Task<SelectCommodityListResp> SelectCommodityList(SelectCommodityListInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            RefAsync<int> total = 0;
            var list = await _db.Queryable<WareBank>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.KeyWord),
                t1 => t1.WareCode.Contains(input.KeyWord) || t1.WareName.Contains(input.KeyWord))
                .WhereIF(input.IsSetClassify.HasValue, t1 => t1.IsClassify == input.IsSetClassify)
                .WhereIF(input.IsGuessWhatYouLikeValue.HasValue, t1 =>
                  t1.IsGuessWhatYouLike == input.IsGuessWhatYouLikeValue)
                .WhereIF(input.CategoryId.HasValue, t1 => t1.CategoryId == input.CategoryId)
                .WhereIF(input.StartDate.HasValue && input.EndDate.HasValue,
                t1 => t1.CreateTime >= input.StartDate && t1.CreateTime < input.EndDate)
                .Select(t1 => new SelectCommodityListOutPut
                {
                    Price = t1.Price,
                    Stock = t1.Stock,
                    WareName = t1.WareName,
                    WareCode = t1.WareCode,
                    WareDetail = t1.WareDetail,
                    CategoryId = t1.CategoryId,
                    CreateMan = t1.CreateMan,
                    CreateTime = t1.CreateTime,
                    UpdateMan = t1.UpdateMan,
                    UpdateTime = t1.UpdateTime,
                    IsClassify = t1.IsClassify,
                    IsGuessWhatYouLike = t1.IsGuessWhatYouLike,
                    WareState = t1.WareState,
                    UndercarriageTime = t1.UndercarriageTime,
                })
                .MergeTable()
                .OrderByDescending(t => t.CreateTime)
                .ToPageListAsync(input.Page, input.PageSize, total);

            var imges = await _db.Queryable<Images>()
                .Where(it => list.Select(t => t.WareCode).Contains(it.Code)).ToListAsync();

            var categorys = await _db.Queryable<Category>()
                .Where(it => list.Select(t => t.CategoryId).Contains(it.Id)).ToListAsync();

            foreach (var item in list)
            {
                item.Path = imges.FirstOrDefault(it => it.Code == item.WareCode)?.Url ?? string.Empty;
                item.CategoryName = categorys
                    .FirstOrDefault(it => it.Id == item.CategoryId)?.Name ?? string.Empty;
            }

            return new SelectCommodityListResp
            {
                Total = total,
                List = list,
                StatusCode = 200,
                Message = "调用成功"
            };
        }

        /// <summary>
        /// 商品列表-是否设置到点单或者猜你喜欢
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task IsSetOrderMealOrGuessWhatYouLike(IsSetOrderMealOrGuessWhatYouLikeInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            if (string.IsNullOrWhiteSpace(input.WareCode))
            {
                throw Oops.Bah("商品编码不能为空");
            }

            var ware = await _db.Queryable<WareBank>()
                .FirstAsync(it => it.WareCode == input.WareCode) ?? throw Oops.Bah("商品不存在");

            ware.IsClassify = input.IsClassify;
            ware.IsGuessWhatYouLike = input.IsGuessWhatYouLike;

            int count = await _db.Updateable(ware)
                .WhereColumns(it => it.WareCode)
                .UpdateColumns(it => new
                {
                    it.IsClassify,
                    it.IsGuessWhatYouLike,
                }).ExecuteCommandAsync();
            if (count < 1) throw Oops.Bah("设置失败");

        }

        /// <summary>
        /// 商品列表-设置商品状态
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseStatus> SetWareState(SetWareStateInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            if (string.IsNullOrWhiteSpace(input.WareCode))
            {
                throw Oops.Bah("商品编码没传进来=>【SetWareState】");
            }

            var ware = await _db.Queryable<WareBank>()
                .FirstAsync(it => it.WareCode == input.WareCode)
                ?? throw Oops.Bah("商品信息错误=>【SetWareState】");

            ware.WareState = input.WareState;
            // 判断 下架才设置下架时间
            if (input.WareState == 0)
            {
                ware.UndercarriageTime = DateTime.Now;
            }

            int count = await _db.Updateable(ware).WhereColumns(it => it.WareCode)
                .UpdateColumns(it => new
                {
                    it.WareState,
                    it.UndercarriageTime
                }).ExecuteCommandAsync();

            if (count < 1)
            {
                throw Oops.Bah("设置失败=>【SetWareState】");
            }

            var output = new ResponseStatus
            {
                StatusCode = 200,
                Message = input.WareState == 0 ? $"商品：{input.WareCode}-【已下架设置成功】" : $"商品：{input.WareCode}-【售卖中设置成功】"
            };

            return output;
        }


        /// <summary>
        /// 类目设置-获取类目列表
        /// </summary>
        /// <returns></returns>
        public async Task<SelectCategoryListResp> SelectCategoryList(SelectCategoryListInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            RefAsync<int> total = 0;
            var list = await _db.Queryable<Category>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.KeyWord), it => it.Name.Contains(input.KeyWord) || it.Id == input.KeyWord.ObjToInt())
                .Select(it => new SelectCategoryListOutPut
                {
                    Id = it.Id,
                    Name = it.Name,
                    Sort = it.Sort
                })
                .OrderBy(it => it.Sort)
                .ToPageListAsync(input.Page, input.PageSize, total);

            return new SelectCategoryListResp
            {
                Message = "调用成功",
                StatusCode = 200,
                List = list,
                Total = total
            };
        }

        /// <summary>
        /// 类目设置-更新排序
        /// </summary>
        /// <returns></returns>
        public async Task UpdateSort(UpdateSortInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            if (!input.Id.HasValue && !input.Sort.HasValue)
            {
                throw Oops.Bah("序号不能为空");
            }

            var categorie = await _db.Queryable<Category>()
                .FirstAsync(it => it.Id == input.Id) ?? throw Oops.Bah("类目不存在");

            if (categorie.Sort == input.Sort.Value)
            {
                throw Oops.Bah("序号并未修改");
            }

            categorie.Sort = input.Sort.Value;

            int count = await _db.Updateable(categorie)
                .WhereColumns(it => it.Id)
                .UpdateColumns(it => new
                {
                    it.Sort,
                }).ExecuteCommandAsync();
            if (count < 1) throw Oops.Bah("更新失败");
        }

        /// <summary>
        /// 新增类目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task AddCategorie(AddCategorieInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            if (string.IsNullOrWhiteSpace(input.Name))
            {
                throw Oops.Bah("请输入类目名称");
            }

            if (!input.Sort.HasValue)
            {
                int sort = await _db.Queryable<Category>().MaxAsync(it => it.Sort);

                input.Sort = ++sort;
            }

            var categorie = await _db.Queryable<Category>()
                .FirstAsync(it => it.Name == input.Name);
            if (categorie != null) throw Oops.Bah("该类目已存在！");

            int count = await _db.Insertable(new Category
            {
                Name = input.Name,
                Sort = input.Sort.Value,
                CreateMan = "",
                CreateTime = DateTime.Now,
                IsDelete = false
            }).IgnoreColumns(it => it.Id).ExecuteCommandAsync();
            if (count < 1)
            {
                throw Oops.Bah("新增失败！");
            }
        }

        /// <summary>
        /// 删除类目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task DeleteCategory(DeleteCategoryInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            if (input.Ids?.Count < 1)
            {
                throw Oops.Bah("请选中类目进行删除[DeleteCategory]");
            }

            // 两种方法都可用

            //var categoryids = await _db.Queryable<Category>()
            //    .Where(it => input.Ids.Contains(it.Id)).Select(it => it.Id).ToListAsync();

            //int count = await _db.Deleteable<Category>().Where(it => categoryids.Contains(it.Id))
            //    .ExecuteCommandAsync();

            var categoryids1 = await _db.Queryable<Category>()
              .Where(it => input.Ids.Contains(it.Id)).ToListAsync();

            int count = await _db.Deleteable<Category>().WhereColumns(categoryids1, it => it.Id)
                .ExecuteCommandAsync();

            if (count < 1) throw Oops.Bah("删除失败");
        }

        /// <summary>
        /// 商品管理-编辑-获取商品详情
        /// </summary>
        /// <param name="WareCode"></param>
        /// <returns></returns>
        public async Task<SelectWareInfoOutput> SelectWareInfo(SelectWareInfoInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input.WareCode);

            if (string.IsNullOrEmpty(input.WareCode)) { throw Oops.Bah("商品编码不能为空"); }

            var ware = await _db.Queryable<WareBank>()
                .FirstAsync(it => it.WareCode == input.WareCode) ?? throw Oops.Bah("商品不存在");

            var images = await _db.Queryable<Images>()
                .Where(it => it.Code == ware.WareCode).ToListAsync();

            // 主图
            var mainImages = images.Where(it => it.Type == "Main").Select(it => it.Url).ToList();

            // 详情图
            var detailImages = images.Where(it => it.Type == "Detail").Select(it => it.Url).ToList();


            return new SelectWareInfoOutput
            {
                WareCode = ware.WareCode,
                CategoryId = ware.CategoryId,
                IsGuessWhatYouLike = ware.IsGuessWhatYouLike,
                IsClassify = ware.IsClassify,
                Price = ware.Price,
                WareDetail = ware.WareDetail,
                WareName = ware.WareName,
                MainImages = mainImages,
                DetailImages = detailImages,
                Message = "请求成功",
                StatusCode = 200
            };
        }


        /// <summary>
        /// 商品管理-保存编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResponseStatus> UpdateCommodity(UpdateCommodityInput input)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input.WareCode);

            var ware = await _db.Queryable<WareBank>()
                .FirstAsync(it => it.WareCode == input.WareCode) ?? throw Oops.Bah("商品不存在");

            ware.CategoryId = input.CategoryId;
            ware.WareDetail = input.WareDetail;
            ware.WareName = input.WareName;
            ware.Price = input.Price;
            ware.IsGuessWhatYouLike = input.IsGuessWhatYouLike;
            ware.IsClassify = input.IsClassify;
            ware.UpdateMan = user.UserName;
            ware.UpdateTime = DateTime.Now;

            var images = await _db.Queryable<Images>()
                .Where(it => input.WareCode == it.Code).Select(it => it.Url).ToListAsync();

            // 把原有的图片过滤，仅新增新的图片
            List<string> newMainImages = new();
            List<string> newDetailImages = new();
            foreach (var mainImages in input.MainImages)
            {
                // 判断，取数据库中images 不包含有现在传入的图片url
                if (!images.Any(url => url == mainImages))
                {
                    newMainImages.Add(mainImages);
                }
            }
            foreach (var detailImages in input.DetailImages)
            {
                // 判断，取数据库中images 不包含有现在传入的图片url
                if (!images.Any(url => url == detailImages))
                {
                    newDetailImages.Add(detailImages);
                }
            }

            // 调用公共添加图片接口
            await _addImageService.InsertImagesAsync(newMainImages, input.WareCode, "Main", user.UserName);

            await _addImageService.InsertImagesAsync(newDetailImages, input.WareCode, "Detail", user.UserName);

            var count = await _db.Updateable(ware)
                .WhereColumns(it => it.WareCode)
                .UpdateColumns(it => new
                {
                    it.WareName,
                    it.Price,
                    it.IsGuessWhatYouLike,
                    it.IsClassify,
                    it.UpdateMan,
                    it.UpdateTime,
                    it.CategoryId,
                    it.WareDetail,
                })
                .ExecuteCommandAsync();
            if (count < 1)
            {
                throw Oops.Bah("修改失败=>【UpdateCommodity】");
            }

            return new ResponseStatus { Message = "修改成功", StatusCode = 200 };
        }

        /// <summary>
        /// 发布商品
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResponseStatus> CommodityRelease(CommodityReleaseInput input)
        {

            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限访问接口");

            // 去掉前后空格
            ToolHelper.TrimStrings(input);

            if (string.IsNullOrWhiteSpace(input.WareName)) throw Oops.Bah("请输入商品名称");
            if (string.IsNullOrWhiteSpace(input.WareDetail)) throw Oops.Bah("请输入商品详情");
            if (input.Price < (decimal)0.01) throw Oops.Bah("商品价格不能小于0.01");
            if (!input.CategoryId.HasValue) throw Oops.Bah("请选择商品类型");
            if (input.Stock < 1) throw Oops.Bah("库存不能小于1");
            if (input.MainImages == null || input.MainImages.Count < 1)
                throw Oops.Bah("商品主图至少上传一张");
            if (input.DetailImages == null || input.DetailImages.Count < 1)
                throw Oops.Bah("商品详情图图至少上传一张");

            // 获取当前事件
            var now = DateTime.Now;
            // 格式：HYQY + 年(4位) + 月 + 日 + 时 + 分 + 秒 + 毫秒(4位)
            string time = now.ToString("yyyyMMddHHmmssfffff");
            // 生成商品编码
            var wareCode = $"HYQY{time}";

            // 调用公共添加图片接口
            await _addImageService.InsertImagesAsync(input.MainImages, wareCode, "Main", user.UserName);

            await _addImageService.InsertImagesAsync(input.DetailImages, wareCode, "Detail", user.UserName);

            // 新增商品
            var count = await _db.Insertable(new WareBank
            {
                CategoryId = (int)input.CategoryId,
                WareName = input.WareName,
                WareDetail = input.WareDetail,
                WareCode = wareCode,
                Price = input.Price,
                Stock = input.Stock,
                WareState = input.WareState,
                IsGuessWhatYouLike = false,
                IsClassify = false,
                CreateMan = user.UserName,
                CreateTime = now,
                IsDelete = false,
            }).ExecuteCommandAsync();

            if (count < 1)
            {
                throw Oops.Bah("商品发布失败=>【CommodityRelease】");
            }


            return new ResponseStatus { StatusCode = 200, Message = "商品发布成功！" };
        }

    }
}
